﻿using ABCNet.Authorization.Users;
using ABCNet.Configuration;
using ABCNet.PlatformFinancialLists;
using ABCNet.UserFinancialLists;
using ABCNet.WithdrawCashs.Dto;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABCNet.WithdrawCashs
{
    /// <summary>
    /// 提现申请相关
    /// </summary>
    public class WithdrawCashAppService : ABCNetAppServiceBase
    {

        private readonly IRepository<WithdrawCash> _repository;
        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<UserFinancialList> _financialRepository;
        private readonly IRepository<PlatformFinancialList> _repositoryPlatformFinancialList;
        private readonly IRepository<PlatformInfos.PlatformInfo> _platformInfoRepository;
        public static ABCSettings _ABCSettings;

        public WithdrawCashAppService(IRepository<WithdrawCash> repository,
            IRepository<User, long> userRepository,
            IRepository<UserFinancialList> financialRepository,
            IRepository<PlatformFinancialList> repositoryPlatformFinancialList,
            IRepository<PlatformInfos.PlatformInfo> platformInfoRepository,
            IOptions<ABCSettings> settings)
        {
            _repository = repository;
            _userRepository = userRepository;
            _financialRepository = financialRepository;
            _repositoryPlatformFinancialList = repositoryPlatformFinancialList;
            _platformInfoRepository = platformInfoRepository;
            _ABCSettings = settings.Value;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<WithdrawCashDto>> GetWithdrawCashPageList(WithdrawCashQueryInput input)
        {
            var query = from wc in _repository.GetAll()
                            .WhereIf(AbpSession.AccountType == AccountTypes.会员账户, x => x.CreatorUserId == AbpSession.UserId)
                            .WhereIf(input.WithdrawState != null && input.WithdrawState.HasValue, x => x.WithdrawState == input.WithdrawState.Value)
                            .WhereIf(input.StartDate != null && input.StartDate.HasValue, x => x.CreationTime >= input.StartDate.Value.Date)
                            .WhereIf(input.EndDate != null && input.EndDate.HasValue, x => x.CreationTime < input.EndDate.Value.Date.AddDays(1))
                        join user in _userRepository.GetAll() on wc.CreatorUserId equals user.Id
                        orderby wc.CreationTime descending
                        select new WithdrawCashDto()
                        {
                            Id = wc.Id,
                            Amount = wc.Amount,
                            AuditTime = wc.AuditTime,
                            CreationTime = wc.CreationTime,
                            CreatorUserId = wc.CreatorUserId,
                            WithdrawState = wc.WithdrawState,
                            PaymentTime = wc.PaymentTime,
                            UserName = user.UserName,
                            Name = user.Name,
                            Bank = user.Bank,
                            BankCardNumber = user.BankCardNumber
                        };

            //总行数
            var totalCount = await query.CountAsync();

            int startIndex = (input.StartPage - 1) * input.PageCount;
            query = query.Skip(startIndex).Take(input.PageCount);
            //获取对象
            var rlst = await query.ToListAsync();

            //组装分页返回对象
            var PagedResult = new PagedResultDto<WithdrawCashDto>(totalCount, rlst);
            return PagedResult;
        }


        public async Task Create(WithdrawCashInput input)
        {
            if (AbpSession.AccountType != AccountTypes.会员账户)
                throw new UserFriendlyException("只有用户才能提现！");
            if (input.Amount <= 0)
                throw new UserFriendlyException("提现金额必须大于0！");
            var user = await GetCurrentUserAsync();
            if (user.AvailableBalance < input.Amount)
                throw new UserFriendlyException("提现金额不能大于可用余额！");

            var model = input.MapTo<WithdrawCash>();
            //保存申请单
            model.WithdrawState = WithdrawStates.待审核;
            await _repository.InsertAndGetIdAsync(model);

            //提现手续费
            decimal sxf = input.Amount * _ABCSettings.提现手续费;
            //实际到账
            decimal daozhang = input.Amount - sxf;

            //记录提现流水
            var ufl = new UserFinancialList
            {
                ChangedAmount = -daozhang,
                UserId = model.CreatorUserId.Value,
                BusinessId = model.Id,
                UBusinessType = UBusinessTypes.用户提现,
                UBusinessTypeName = nameof(UBusinessTypes.用户提现),
                BeforeChangedAmount = user.AvailableBalance,
                AfterChangedAmount = user.AvailableBalance - daozhang
            };
            await _financialRepository.InsertAndGetIdAsync(ufl);
            //记录提现流水
            var uflsxf = new UserFinancialList
            {
                ChangedAmount = -sxf,
                UserId = model.CreatorUserId.Value,
                BusinessId = model.Id,
                UBusinessType = UBusinessTypes.提现手续费,
                UBusinessTypeName = nameof(UBusinessTypes.提现手续费),
                BeforeChangedAmount = user.AvailableBalance,
                AfterChangedAmount = user.AvailableBalance - sxf
            };
            await _financialRepository.InsertAndGetIdAsync(uflsxf);
            
            //平台记录扣手续费
            var platformInfo = _platformInfoRepository.GetAll().First();
            //平台收入
            var pfl = new PlatformFinancialList
            {
                ChangedAmount = sxf,
                BusinessId = model.Id,
                UserId = model.CreatorUserId.Value,
                BusinessType = BusinessTypes.提现手续费,
                BusinessTypeName = nameof(BusinessTypes.提现手续费),
                BeforeChangedAmount = platformInfo.AvailableBalance,
                AfterChangedAmount = platformInfo.AvailableBalance + sxf,
                NetPointId = 0
            };
            _repositoryPlatformFinancialList.InsertAndGetId(pfl);
            //更新平台余额
            _platformInfoRepository.Update(platformInfo.Id, x => x.AvailableBalance += sxf);
            
            //扣减余额
            user.AvailableBalance -= input.Amount;
            await _userRepository.UpdateAsync(user);
        }


        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public void Auditing(EntityDto input)
        {
            if (AbpSession.AccountType != AccountTypes.后台账户)
                throw new UserFriendlyException("只有管理员才能审核！");
            var w = _repository.Get(input.Id);
            if (w.WithdrawState == WithdrawStates.待审核)
            {
                w.WithdrawState = WithdrawStates.待转账;
                w.AuditorId = AbpSession.UserId;
                w.AuditTime = Abp.Timing.Clock.Now;
                _repository.Update(w);
            }
        }

        /// <summary>
        /// 未通过
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task NotThrough(EntityDto input)
        {
            if (AbpSession.AccountType != AccountTypes.后台账户)
                throw new UserFriendlyException("只有管理员才能审核！");
            var w = _repository.Get(input.Id);
            //处理申请单
            if (w.WithdrawState == WithdrawStates.待审核)
            {
                w.WithdrawState = WithdrawStates.未通过;
                w.AuditorId = AbpSession.UserId;
                w.AuditTime = Abp.Timing.Clock.Now;
                _repository.Update(w);
            }

            var fLst = _financialRepository.GetAll().Where(f => f.BusinessId == w.Id && (f.UBusinessType == UBusinessTypes.用户提现 || f.UBusinessType == UBusinessTypes.提现手续费)).ToList();

            var user = _userRepository.Get(w.CreatorUserId.Value);
            decimal userAvailableBalance = user.AvailableBalance;
            decimal sxf = 0;
            foreach (var item in fLst)
            {
                decimal changedAmount = 0;
                UBusinessTypes uBusinessType;
                string uBusinessTypeName;
                if (item.UBusinessType == UBusinessTypes.用户提现)
                {
                    sxf = -item.ChangedAmount;
                    changedAmount = -item.ChangedAmount;
                    uBusinessType = UBusinessTypes.撤销用户提现;
                    uBusinessTypeName = nameof(UBusinessTypes.撤销用户提现);
                }
                else
                {
                    changedAmount = -item.ChangedAmount;
                    uBusinessType = UBusinessTypes.撤销提现手续费;
                    uBusinessTypeName = nameof(UBusinessTypes.撤销提现手续费);
                }

                var ufl = new UserFinancialList
                {
                    ChangedAmount = changedAmount,
                    UserId = w.CreatorUserId.Value,
                    BusinessId = w.Id,
                    UBusinessType = uBusinessType,
                    UBusinessTypeName = uBusinessTypeName,
                    BeforeChangedAmount = userAvailableBalance,
                    AfterChangedAmount = userAvailableBalance + changedAmount
                };
                userAvailableBalance += changedAmount;
                await _financialRepository.InsertAndGetIdAsync(ufl);
            }
            //扣减余额
            user.AvailableBalance += w.Amount;
            await _userRepository.UpdateAsync(user);

            //平台记录增加手续费
            var platformInfo = _platformInfoRepository.GetAll().First();
            //平台收入
            var pfl = new PlatformFinancialList
            {
                ChangedAmount = -sxf,
                BusinessId = w.Id,
                UserId = w.CreatorUserId.Value,
                BusinessType = BusinessTypes.撤销提现手续费,
                BusinessTypeName = nameof(BusinessTypes.撤销提现手续费),
                BeforeChangedAmount = platformInfo.AvailableBalance,
                AfterChangedAmount = platformInfo.AvailableBalance - sxf,
                NetPointId = 0
            };
            _repositoryPlatformFinancialList.InsertAndGetId(pfl);
            //更新平台余额
            _platformInfoRepository.Update(platformInfo.Id, x => x.AvailableBalance -= sxf);

        }

        /// <summary>
        /// 完成申请单（已付款）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public void Complete(EntityDto input)
        {
            if (AbpSession.AccountType != AccountTypes.后台账户)
                throw new UserFriendlyException("只有管理员才能审核！");
            var w = _repository.Get(input.Id);
            if (w.WithdrawState == WithdrawStates.待转账)
            {
                w.WithdrawState = WithdrawStates.已完成;
                w.AccountantId = AbpSession.UserId;
                w.PaymentTime = Abp.Timing.Clock.Now;
                _repository.Update(w);
            }
        }

    }
}
